/**
 * 统一WebSocket服务 - 整合了WebSocketManager和WebSocketPool的功能
 * 提供统一的API接口，避免双重管理架构问题
 */

import {
  WebSocketPool,
  ConnectionState,
  type WebSocketConfig,
  type MessageHandler,
  type StateChangeHandler
} from '@/utils/websocket-pool';
import { globalPerformanceMonitor } from '@/utils/performance-monitor';

// 数据解析规则配置
export interface DataParsingRule {
  dataPath?: string;
  pointExtraction: 'auto' | 'manual' | 'custom';
  excludeFields?: string[];
  fieldMappings?: Array<{
    sourcePath: string;
    pointId: string;
  }>;
  customParser?: string;
}

// 数据源配置
export interface DataSource {
  id: string;
  name: string;
  url: string;
  enabled: boolean;
  description?: string;
  parsingRule?: DataParsingRule;
  protocols?: string | string[];
}

// 统一的消息格式
export interface WSMessage {
  type: string;
  data: any;
  timestamp?: number;
  source?: string;
}

/**
 * 统一WebSocket服务类
 * 基于WebSocketPool实现，提供简化的API接口
 */
export class UnifiedWebSocketService {
  private pool: WebSocketPool;
  private dataSourceConnections = new Map<string, string>(); // dataSourceId -> connectionId
  private messageHandlers = new Map<string, (message: WSMessage) => void>();
  private globalMessageHandler: ((message: WSMessage) => void) | null = null;
  private destroyed = false;

  constructor(poolConfig?: any) {
    this.pool = new WebSocketPool(poolConfig);
    this.setupEventHandlers();

    // 页面卸载时自动清理
    this.addUnloadListener();
  }

  /**
   * 设置事件处理器
   */
  private setupEventHandlers(): void {
    // 统一消息处理
    this.pool.addMessageHandler((data: any, connectionId: string) => {
      const message: WSMessage = {
        type: data.type || 'data',
        data: data.data || data,
        timestamp: data.timestamp || Date.now(),
        source: this.getDataSourceIdByConnectionId(connectionId)
      };

      // 调用特定数据源的处理器
      const dataSourceId = this.getDataSourceIdByConnectionId(connectionId);
      if (dataSourceId) {
        const handler = this.messageHandlers.get(dataSourceId);
        if (handler) {
          try {
            handler(message);
          } catch (error) {
            console.error(`数据源 ${dataSourceId} 消息处理失败:`, error);
          }
        }
      }

      // 调用全局处理器
      if (this.globalMessageHandler) {
        try {
          this.globalMessageHandler(message);
        } catch (error) {
          console.error('全局消息处理失败:', error);
        }
      }
    });

    // 连接状态变化处理
    this.pool.addStateChangeHandler((connectionId: string, state: ConnectionState) => {
      const dataSourceId = this.getDataSourceIdByConnectionId(connectionId);
      if (dataSourceId) {
        globalPerformanceMonitor.recordEvent({
          type: 'websocket-state-change',
          data: { dataSourceId, connectionId, state }
        });
      }
    });
  }

  /**
   * 添加页面卸载监听器
   */
  private addUnloadListener(): void {
    const handleUnload = () => {
      this.destroy();
    };

    window.addEventListener('beforeunload', handleUnload);
    window.addEventListener('pagehide', handleUnload);

    // 存储引用用于清理
    (this as any)._unloadHandler = handleUnload;
  }

  /**
   * 移除页面卸载监听器
   */
  private removeUnloadListener(): void {
    const handler = (this as any)._unloadHandler;
    if (handler) {
      window.removeEventListener('beforeunload', handler);
      window.removeEventListener('pagehide', handler);
      delete (this as any)._unloadHandler;
    }
  }

  /**
   * 根据连接ID获取数据源ID
   */
  private getDataSourceIdByConnectionId(connectionId: string): string | undefined {
    for (const [dataSourceId, connId] of this.dataSourceConnections) {
      if (connId === connectionId) {
        return dataSourceId;
      }
    }
    return undefined;
  }

  /**
   * 验证WebSocket URL格式
   */
  private isValidWebSocketUrl(url: string): boolean {
    if (!url || typeof url !== 'string') {
      return false;
    }

    if (!url.startsWith('ws://') && !url.startsWith('wss://')) {
      return false;
    }

    try {
      new URL(url);
      return true;
    } catch {
      return false;
    }
  }

  /**
   * 设置全局消息处理器
   */
  setGlobalMessageHandler(handler: (message: WSMessage) => void): void {
    this.globalMessageHandler = handler;
  }

  /**
   * 移除全局消息处理器
   */
  removeGlobalMessageHandler(): void {
    this.globalMessageHandler = null;
  }

  /**
   * 设置数据源消息处理器
   */
  setMessageHandler(dataSourceId: string, handler: (message: WSMessage) => void): void {
    this.messageHandlers.set(dataSourceId, handler);
  }

  /**
   * 移除数据源消息处理器
   */
  removeMessageHandler(dataSourceId: string): void {
    this.messageHandlers.delete(dataSourceId);
  }

  /**
   * 连接到数据源
   */
  async connect(dataSource: DataSource): Promise<boolean> {
    if (this.destroyed) {
      console.warn('WebSocket服务已销毁，无法建立连接');
      return false;
    }

    // 检查是否已连接
    if (this.dataSourceConnections.has(dataSource.id)) {
      console.warn(`数据源 ${dataSource.id} 已存在连接`);
      return false;
    }

    // 验证URL
    if (!this.isValidWebSocketUrl(dataSource.url)) {
      console.error(`无效的WebSocket URL: ${dataSource.url}`);
      return false;
    }

    try {
      const connectionId = await this.pool.createConnection({
        url: dataSource.url,
        protocols: dataSource.protocols,
        reconnectInterval: 5000,
        maxReconnectAttempts: 5,
        heartbeatInterval: 30000,
        connectionTimeout: 10000,
        maxMessageQueueSize: 100
      });

      this.dataSourceConnections.set(dataSource.id, connectionId);

      globalPerformanceMonitor.recordEvent({
        type: 'websocket-datasource-connected',
        data: { dataSourceId: dataSource.id, connectionId, url: dataSource.url }
      });

      return true;
    } catch (error) {
      console.error(`连接数据源 ${dataSource.id} 失败:`, error);
      return false;
    }
  }

  /**
   * 断开数据源连接
   */
  disconnect(dataSourceId: string): void {
    const connectionId = this.dataSourceConnections.get(dataSourceId);
    if (!connectionId) {
      console.warn(`数据源 ${dataSourceId} 未找到对应连接`);
      return;
    }

    this.pool.closeConnection(connectionId);
    this.dataSourceConnections.delete(dataSourceId);
    this.messageHandlers.delete(dataSourceId);

    globalPerformanceMonitor.recordEvent({
      type: 'websocket-datasource-disconnected',
      data: { dataSourceId, connectionId }
    });
  }

  /**
   * 发送消息到指定数据源
   */
  send(dataSourceId: string, message: any): boolean {
    const connectionId = this.dataSourceConnections.get(dataSourceId);
    if (!connectionId) {
      console.error(`数据源 ${dataSourceId} 未找到连接`);
      return false;
    }

    return this.pool.sendMessage(connectionId, message);
  }

  /**
   * 广播消息到所有数据源
   */
  broadcast(message: any): number {
    return this.pool.broadcast(message);
  }

  /**
   * 获取数据源连接状态
   */
  getConnectionStatus(dataSourceId: string): string {
    const connectionId = this.dataSourceConnections.get(dataSourceId);
    if (!connectionId) {
      return 'disconnected';
    }

    const details = this.pool.getConnectionDetails();
    const connection = details.find((conn) => conn.id === connectionId);
    return connection ? connection.state : 'disconnected';
  }

  /**
   * 获取所有数据源状态
   */
  getAllConnectionStatus(): { [dataSourceId: string]: string } {
    const status: { [dataSourceId: string]: string } = {};

    for (const [dataSourceId] of this.dataSourceConnections) {
      status[dataSourceId] = this.getConnectionStatus(dataSourceId);
    }

    return status;
  }

  /**
   * 重连指定数据源
   */
  async reconnect(dataSourceId: string): Promise<boolean> {
    // 先断开现有连接
    this.disconnect(dataSourceId);

    // 这里需要重新连接，但我们需要数据源配置
    console.warn(`重连 ${dataSourceId} 需要提供完整的数据源配置`);
    return false;
  }

  /**
   * 更新数据源配置
   */
  async updateDataSources(dataSources: DataSource[]): Promise<void> {
    const currentDataSourceIds = new Set(this.dataSourceConnections.keys());
    const newDataSourceIds = new Set(dataSources.filter((ds) => ds.enabled).map((ds) => ds.id));

    // 断开不再需要的连接
    for (const dataSourceId of currentDataSourceIds) {
      if (!newDataSourceIds.has(dataSourceId)) {
        this.disconnect(dataSourceId);
      }
    }

    // 建立新的连接
    for (const dataSource of dataSources) {
      if (dataSource.enabled && !currentDataSourceIds.has(dataSource.id)) {
        await this.connect(dataSource);
      }
    }
  }

  /**
   * 获取连接池统计信息
   */
  getStats() {
    const poolStats = this.pool.getPoolStats();
    return {
      ...poolStats,
      dataSourceCount: this.dataSourceConnections.size,
      handlerCount: this.messageHandlers.size,
      hasGlobalHandler: !!this.globalMessageHandler
    };
  }

  /**
   * 获取数据源连接详情
   */
  getDataSourceDetails() {
    const poolDetails = this.pool.getConnectionDetails();
    return Array.from(this.dataSourceConnections.entries()).map(([dataSourceId, connectionId]) => {
      const connection = poolDetails.find((conn) => conn.id === connectionId);
      return {
        dataSourceId,
        connectionId,
        connection: connection || null,
        hasHandler: this.messageHandlers.has(dataSourceId)
      };
    });
  }

  /**
   * 销毁服务，清理所有资源
   */
  destroy(): void {
    if (this.destroyed) {
      return;
    }

    console.log('销毁WebSocket服务，清理所有连接和资源');

    // 标记为已销毁
    this.destroyed = true;

    // 清理所有连接
    this.pool.destroy();

    // 清理映射关系
    this.dataSourceConnections.clear();
    this.messageHandlers.clear();
    this.globalMessageHandler = null;

    // 移除页面卸载监听器
    this.removeUnloadListener();

    globalPerformanceMonitor.recordEvent({
      type: 'websocket-service-destroyed',
      data: { timestamp: Date.now() }
    });
  }

  /**
   * 检查服务是否已销毁
   */
  isDestroyed(): boolean {
    return this.destroyed;
  }
}

// 创建全局统一WebSocket服务实例
export const unifiedWebSocketService = new UnifiedWebSocketService({
  maxConnections: 8,
  healthCheckInterval: 30000,
  loadBalancingStrategy: 'least-connections'
});

// 便捷API
export const connectDataSource = (dataSource: DataSource) => {
  return unifiedWebSocketService.connect(dataSource);
};

export const disconnectDataSource = (dataSourceId: string) => {
  return unifiedWebSocketService.disconnect(dataSourceId);
};

export const sendToDataSource = (dataSourceId: string, message: any) => {
  return unifiedWebSocketService.send(dataSourceId, message);
};

export const broadcastToAll = (message: any) => {
  return unifiedWebSocketService.broadcast(message);
};

export const getDataSourceStatus = (dataSourceId: string) => {
  return unifiedWebSocketService.getConnectionStatus(dataSourceId);
};

export const getAllDataSourceStatus = () => {
  return unifiedWebSocketService.getAllConnectionStatus();
};

export const setGlobalMessageHandler = (handler: (message: WSMessage) => void) => {
  return unifiedWebSocketService.setGlobalMessageHandler(handler);
};

export const setDataSourceMessageHandler = (
  dataSourceId: string,
  handler: (message: WSMessage) => void
) => {
  return unifiedWebSocketService.setMessageHandler(dataSourceId, handler);
};

export const getWebSocketStats = () => {
  return unifiedWebSocketService.getStats();
};

export default unifiedWebSocketService;
